import axios from 'axios'
import store from '@/store'
import Vue from 'vue'
import { postLogin, getDevice } from "@/common/js/api/api.js";
import { mapState } from 'vuex' //引入mapState
mapState({token: state => state.adminUser.token})
var timeoutStatus = true
var instance = (baseURL, configs) => {
	//直接请求会报错 adapter is not a function
	// 解决方法:使用原生请求uni.request()
	// 自定义适配器来适配uniapp语法
	axios.defaults.adapter = function(config) {
		return new Promise((resolve, reject) => {
			var settle = require('axios/lib/core/settle');
			var buildURL = require('axios/lib/helpers/buildURL');
			uni.request({
				method: config.method.toUpperCase(),
				url: config.baseURL + buildURL(config.url, config.params, config.paramsSerializer),
				header: config.headers,
				data: config.data,
				dataType: config.dataType,
				responseType: config.responseType,
				sslVerify: config.sslVerify,
				complete: function complete(response) {
					// console.log("执行完成：", response)
					response = {
						data: response.data,
						status: response.statusCode,
						errMsg: response.errMsg,
						header: response.header,
						config: config
					};
					settle(resolve, reject, response);
				}
			})
		})
	};
		let instance = axios.create({
			baseURL: baseURL, // 公	共接口url（如果有多个的公共接口的话，需要处理）
			// baseURL: process.env.VUE_APP_BASE_API, // 公	共接口url（如果有多个的公共接口的话，需要处理）
			// timeout: 20000, // 请求超时
		});
		// 请求拦截器, 进行一个全局loading  加载，这种情况下所有的接口请求前 都会加载一个loading
		/**
		 * 添加请求拦截器 ，意思就是发起请求接口之前做什么事，一般都会发起加载一个loading
		 * */
		//  如果不想每个接口都加载loading ，就注释掉请求前拦截器,在http这个类中处理
		instance.interceptors.request.use(config => {
			// 在发送请求之前做些什么（... 这里写你的展示loading的逻辑代码 ）
			// isShowLoading(true);
			// 获取token，配置请求头
			// const TOKEN = localStorage.getItem('Token')
			// 演示的token（注意配置请求头，需要后端做cros跨域处理，我这里自己前端配的跨域）
			// 打印请求数据接口
			if(store.state.adminUser.token) {
				config.headers.Authorization = 'Bearer ' + `${store.state.adminUser.token}`;
				config.headers['Content-Type'] = 'application/json';
			}
			if (configs) {
				for (var key in configs) {
					config[key] = configs[key];
					console.log('config[key]', configs[key])
				}
			}
			return config;
		}, error => {
			// 对请求错误做些什么，处理这个错误
			// 可以直接处理或者展示出去,toast show()
			return Promise.reject(error);
		});
		/**
		 * 添加响应拦截器，意思就是发起接口请求之后做什么事，此时只有两种情况，
		 * 要么成功，要么失败，但是不管成功，还是失败，我们都需要关闭请求之前的
		 * 发起的loading，那既然要处理loading，就把loading做成全局的了，
		 * 这里自定义一个处理加载loding 和关闭loading的方法，而且这个loading
		 * 要不要加载，会根据外部传入的布尔值来决定，默认是false:不展示
		 * */
		instance.interceptors.response.use(function(response) {
			// 对响应数据做点什么
			// isShowLoading(false);
			// 根据你们家的后端定义请求过期后返回的参数，处理token过期问题
			// 我这个接口木有token啊，这里演示下
			// 判断
			const status = response.data.status || response.statusCode;
			// 判断状态码401或者其它条件，不知道判断哪个的去问你家后台
			if (Object.is(status, 401)) {
				console.log("token已过期，请重新登录")
				// token过期后处理
				// 1.删除你本地存储的那个过期的token
				// 2. 跳转到登陆页（因为没有装路由，不写了，重新登陆赋值）
				//  todo...
			}
			if (Object.is(status, 417)) {
				console.log("接口请求失败");
			} 
			if (Object.is(status, 400)) {
				console.log("获取数据失败");
			} 
			if (String(status)[0] == 4 || String(status)[0] == 5) {
				return Promise.reject(response);
			} 
			return response;
		}, function(error) {
			if (error.message.includes('timeout') && timeoutStatus) {
				timeoutStatus = false
				setTimeout(() => {
					timeoutStatus = true
				}, 16000)
			}
			if (error.response) {
				if (error.response.status == 400) {
					return Promise.reject(error.response.data);
				}
			}
			return Promise.reject(error);
		});
		return instance;
	}

function getStr(data) {
	var str = '?'
	var keys = Object.keys(data);
	var values = Object.values(data);
	for (var i = 0; i < keys.length; i++) {
		str = str + keys[i] + '=' + values[i] + '&';
	}
	str = str.slice(0, str.length - 1)
	return str;
};

class http {
	constructor(baseURL) {
		this.baseURL = baseURL
	}
	// 监听token值是否已经获取
	token() {
		return new Promise(function(resolve, reject) {
			let TOKEN = store.state.adminUser.token
			let currentTime = 0; //当前时间
			let time = 20; //定时器间隔
			let timeOver = 60000; //超时时间
			let timer = setInterval(() => {
				TOKEN = store.state.adminUser.token
				// currentTime += time;
				if (TOKEN) {
					clearInterval(timer);
					resolve();
				}
				if (currentTime >= timeOver) {
					clearInterval(timer);
					uni.hideLoading();
					uni.showToast({
						icon: 'none',
						title: '请求超时！请检查网络！'
					})
				} else if (store.state.adminUser.statusCode == 417) {
					clearInterval(timer);
					uni.hideLoading();
					uni.showToast({
						icon: 'none',
						title: '授权登录失败！请先关注公众号！'
					})
				}
			}, time);
		})
	}
	// 使用async ... await
	async get(url,params) {
		let TOKEN = store.state.adminUser.token;
		// #ifdef MP
		if (params) {
			params = getStr(params);
		} else {
			params = ''
		}
		return await instance(this.baseURL).get(url + params)
		// #endif
		return await instance(this.baseURL).get(url, {
			params
		})
	}
	async post(url, params, config = {}) {
		let TOKEN = store.state.adminUser.token;
		if (url != '/auth/login' && url != '/auth/wx/login' ) {
			await this.token();
		}
		return await instance(this.baseURL, config).post(url, params, config);
	}
	
	async put(url, params, config = {}) {
		let TOKEN = store.state.adminUser.token
		if (url != '/auth/wx/login') {
			await this.token();
		}
		let isObject = Object.prototype.toString.call(params) === '[object Object]'
		if (isObject) {
			return await instance(this.baseURL, config).put(url, params, config);
		}
		return await instance(this.baseURL, config).put(url, JSON.stringify(params),
			config);
	}
	// 通过json 传数据
	async delete(url, params) {
		let TOKEN = store.state.adminUser.token;
		return await instance(this.baseURL).delete(url, {
			data: params
		});
	}
	// 通过url 传数据
	async del(url, params, data = "") {
		return await instance(this.baseURL).delete(url, {
			params: params,
			data: data
		});
	}
}
export default http;
